import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

/// create at 2021/7/15
/// by yjl
/// describe：

class RenderBoxStudyPage extends StatefulWidget {
  RenderBoxStudyPage({Key? key}) : super(key: key);

  @override
  _RenderBoxStudyPageState createState() => _RenderBoxStudyPageState();
}

class _RenderBoxStudyPageState extends State<RenderBoxStudyPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("RenderBoxStudyPage"),
      ),
      body: Container(
        color: Colors.blue,
        child: ShadowBox(
          distance: 10,
          child: Icon(Icons.category, size: 80),
        ),
      ),
    );
  }
}

class ShadowBox extends SingleChildRenderObjectWidget {
  final Widget? child;
  final double? distance;

  ShadowBox({this.child, this.distance = 20}) : super(child: child);

  //运行时类型和key一样的话不会重新创建RenderObject
  @override
  RenderObject createRenderObject(BuildContext context) {
    return RenderShadowBox2(distance);
  }

  //因为类型没有变RenderBox就会捡回去继续使用，但是你可以修改RenderBox的属性
  @override
  void updateRenderObject(
      BuildContext context, covariant RenderShadowBox2 renderObject) {
    renderObject.distance = distance;
  }
}

///继承功能相似的RenderBox
class RenderShadowBox extends RenderBox with RenderObjectWithChildMixin {
  double? distance;

  RenderShadowBox(this.distance);

  @override
  void performLayout() {
    //父组件使用子size 因为有些 父组件不需要使用子组件的size
    child?.layout(constraints, parentUsesSize: true);
    //child?.layout(BoxConstraints.tight(Size(50,50)));
    //size = Size(300,300);
    size = (child as RenderBox).size;
  }

  //无中生有
  @override
  void paint(PaintingContext context, Offset offset) {
    context.paintChild(child!, offset);
    var canvas = context.canvas;
    // canvas.drawCircle(offset+Offset(50,50), 50, Paint()..color=Colors.white);
    //建立新的图层
    context.pushOpacity(offset, 127, (context, offset) {
      context.paintChild(
          child!, offset + Offset(distance ?? 20, distance ?? 20));
    });
  }
}

class RenderShadowBox2 extends RenderProxyBox with DebugOverflowIndicatorMixin {
  double? distance;

  RenderShadowBox2(this.distance);

  //无中生有
  @override
  void paint(PaintingContext context, Offset offset) {
    context.paintChild(child!, offset);
    context.pushOpacity(offset, 127, (context, offset) {
      context.paintChild(
          child!, offset + Offset(distance ?? 20, distance ?? 20));
    });
    //开发者 自己画的
    paintOverflowIndicator(
      context,
      offset,
      //能画的区域
      //Rect.fromLTWH(0, 0, size.width, size.height),
      Offset.zero & size,
      //子组件要画的区域
      //Rect.fromLTWH(0, 0, 320, 300),
      Offset.zero & child!.size,
    );
  }
}
